from flask import Blueprint, render_template, \
    current_app, request, flash, redirect, url_for, jsonify
from flask_login import login_required
from app.models.article import Article
from app.models.category import Category
from app.models.user import User
from app.models.companys import Companys
from app.forms.article import ArticleForm, UpdateArticleForm, EditArticleForm
from app.forms.common import AjaxDeleteForm, FileUploadForm
from datetime import datetime
from flask_ckeditor import upload_success, upload_fail
from app.extensions import db
from uuid import uuid4
from flask_login import current_user
from app.helpers import oss_bucket
from app.decorators import permission_required
import json

bp = Blueprint('article', __name__)


@bp.before_request
@login_required
def before_request():
    pass


@bp.context_processor
def make_template_context():
    return dict(category=Category.query.all())


@bp.route('/')
@permission_required('ARTICLE_INDEX')
def index():
    page = request.args.get('page', 1, type=int)
    is_type = request.args.get('type', None, type=int)
    company_id = request.args.get('company_id', None, type=int)
    query = Article.query.join(User).order_by(Article.id.desc()).filter(Article.status==9)
    company = None
    if company_id:
        company = Companys.query.get_or_404(company_id)
        query = query.filter(User.cid==company_id)

    # if current_user.role.name == 'Edit':
    #     query = query.filter(Article.audit_status <= 9)

    if current_user.role.name == 'Audit':
        query = query.filter(Article.audit_status < 9)

    if current_user.role.name == 'User':
        query = query.filter(Article.uid==current_user.id)

    if current_user.role.name == 'Head':
        query = query.filter(Article.uid.in_([u.id for u in current_user.company.users]))

    hired = query.filter(Article.rid == None).count()
    not_hired = query.filter(Article.rid != None).count()

    if is_type == 2:
        query = query.filter(Article.rid != None)
    elif is_type == 3:
        query = query.filter(Article.rid == None)

    pre_page = current_app.config['POST_PRE_PAGE']
    pagination = query.paginate(page, pre_page)
    return render_template('admin/article/index.html',
                           model=pagination.items,
                           page=page,
                           hired=hired,
                           company=company,
                           not_hired=not_hired,
                           pagination=pagination)


@bp.route('/view/<int:id>', methods=['GET'])
def view(id):
    model = Article.query.get_or_404(id)
    return render_template('admin/article/view.html', model=model)


@bp.route('/create', methods=['GET', 'POST'])
@permission_required('ARTICLE_CREATE')
def create():
    form = ArticleForm()
    cid = request.args.get('cid', type=int)
    model = Article()
    if model.save(form, uid=current_user.id):
        flash('添加文章成功', 'success')
        return redirect(url_for('article.index'))
    form.cid.data = cid

    print(form.errors)
    return render_template('admin/article/create.html', form=form)


@bp.route('/update/<int:id>', methods=['GET', 'POST'])
@permission_required('ARTICLE_UPDATE')
def update(id):
    form = UpdateArticleForm()
    model = Article.query.get_or_404(id)

    if model.audit_status != 10:
        flash('只能修改未通过的文章', 'danger')
        return redirect(request.referrer or url_for('article.index'))


    if model.report:
        flash('不能更新已选用的', 'danger')
        return redirect(request.referrer or url_for('article.index'))

    if model.save(form):
        flash('更新成功', 'success')
        return redirect(url_for('article.index'))

    form.load(model)

    return render_template('admin/article/update.html', form=form, model=model)


@bp.route('/edit/<int:id>', methods=['GET', 'POST'])
@permission_required('ARTICLE_EDIT')
def edit(id):
    form = EditArticleForm()
    model = Article.query.get_or_404(id)

    if model.audit_status not in [9, 8]:
        flash('只能编辑一审通过, 二审提交的', 'danger')
        return redirect(request.referrer or url_for('article.index'))

    if model.report:
        flash('不能更新已选用的', 'danger')
        return redirect(request.referrer or url_for('article.index'))

    if model.save(form):
        flash('更新成功', 'success')
        return redirect(url_for('article.index'))

    form.load(model)

    if model.edit_content is None:
        form.edit_content.data = model.content

    return render_template('admin/article/edit.html', form=form, model=model)


@bp.route('/delete/<int:id>')
@permission_required('ARTICLE_DELETE')
def delete(id):
    physics = request.args.get('physics', type=int)
    model = Article.query.get_or_404(id)
    if model.rid is not None:
        flash('删除失败，文章已给录用，不允许删除!', 'danger')
        return redirect(request.referrer or url_for('article.index'))
    model.delete(True if physics == 1 else False)
    flash('删除成功', 'success')
    return redirect(request.referrer or url_for('article.index'))


@bp.route('/ajax_delete', methods=['POST'])
@permission_required('ARTICLE_DELETE')
def ajax_delete():
    form = AjaxDeleteForm()
    physics = request.args.get('physics', type=int)
    if form.validate_on_submit():
        for i in json.loads(form.ids.data):
            model = Article.query.get_or_404(i)
            if model.rid is not None:
                flash('删除失败，文章已给录用，不允许删除!', 'danger')
                return redirect(request.referrer or url_for('article.index'))
            model.delete(True if physics == 1 else False)
        flash('删除成功', 'success')

    if form.errors:
        flash(form.errors, 'danger')

    return jsonify({'success': True, 'message': '删除成功'})


@bp.route('/audit_status/<int:id>/<int:status>')
@permission_required('ARTICLE_AUDIT_STATUS')
def audit_status(id, status):
    model = Article.query.get_or_404(id)
    if model.report:
        flash('不能修改已用的文章', 'danger')
        return redirect(request.referrer or url_for('article.index'))

    if current_user.role.name == 'Edit':
        if status != 8:
            flash('只能修改8状态', 'danger')
            return redirect(url_for('article.index'))
        if model.edit_content is None:
            flash('没有编辑内容，不能提交', 'danger')
            return redirect(request.referrer or url_for('article.index'))

        with db.auto_commit():
            model.audit_status = status
        flash('操作成功', 'success')
        return redirect(url_for('article.index'))

    if current_user.role.name == 'Head':
        if status not in [10, 9]:
            flash('只能修改10， 9', 'danger')
            return redirect(request.referrer or url_for('article.index'))

    if current_user.role.name in ['Audit', 'Edit']:
        if status not in [8, 7, 6]:
            flash('只能修改8 7 6', 'danger')
            return redirect(request.referrer or url_for('article.index'))

    with db.auto_commit():
        model.audit_status = status
    flash('操作成功', 'success')
    return redirect(request.referrer or url_for('article.index'))




@bp.route('/trash')
@permission_required('ARTICLE_TRASH')
def trash():
    page = request.args.get('page', 1, type=int)
    query = Article.query.filter_by(status=0).order_by(Article.id.desc())
    pre_page = current_app.config['POST_PRE_PAGE']
    pagination = query.paginate(page, pre_page)
    category = Category.query.all()
    return render_template('admin/article/trash.html',
                           model=pagination.items,
                           page=page,
                           pagination=pagination,
                           category=category)


@bp.route('/ajax_restore', methods=['POST'])
@permission_required('ARTICLE_AJAX_RESTORE')
def ajax_restore():
    form = AjaxDeleteForm()
    if form.validate_on_submit():
        for i in json.loads(form.ids.data):
            Article.query.get_or_404(i).status = 9
        flash('还原成功', 'success')
        db.session.commit()

    if form.errors:
        flash(form.errors, 'danger')

    return jsonify({'success': True, 'message': '还原成功'})


@bp.route('/upload', methods=['POST'])
@permission_required('ARTICLE_UPLOAD_IMAGE')
def upload_image():
    fileForm = FileUploadForm()
    if fileForm.validate_on_submit():
        file = request.files.get('upload')
        extension = file.filename.split('.')[1].lower()
        filename = '/'.join([datetime.now().strftime('%Y-%m-%d'), '{}.{}'.format(uuid4(), extension)])
        # filename = os.path.join(datetime.now().strftime('%Y-%m-%d'), '{}.{}'.format(uuid4(), extension))
        oss_bucket.put_object(filename, file.read())
        url = 'https://lsol-house-upload.oss-cn-hangzhou.aliyuncs.com/{}'.format(filename)
        return upload_success(url=url)

    return upload_fail(message=fileForm.errors['upload'])
